package com.yjb.tenet.boot.quartz.controller;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yjb.tenet.boot.common.exception.CustomException;
import com.yjb.tenet.boot.common.exception.enums.ErrorCodeEnum;
import com.yjb.tenet.boot.common.pojo.ResponseResult;
import com.yjb.tenet.boot.quartz.application.manager.SysJobManager;
import com.yjb.tenet.boot.quartz.application.service.SysJobService;
import com.yjb.tenet.boot.quartz.domain.dto.SysJobPageDTO;
import com.yjb.tenet.boot.quartz.domain.form.SysJobAddForm;
import com.yjb.tenet.boot.quartz.domain.form.SysJobEditForm;
import com.yjb.tenet.boot.quartz.domain.form.SysJobStatusForm;
import com.yjb.tenet.boot.quartz.domain.query.SysJobPageQuery;
import com.yjb.tenet.boot.quartz.infrastructure.constants.ScheduleConstants;
import com.yjb.tenet.boot.quartz.infrastructure.utils.ScheduleUtils;
import com.yjb.tenet.boot.system.infrastructure.log.Log;
import com.yjb.tenet.boot.quartz.infrastructure.utils.CronUtils;
import org.quartz.SchedulerException;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.validation.Valid;

/**
 * 定时任务
 * @author yinjinbiao
 * @create 2021/12/15 17:21
 */
@RestController
@RequestMapping("/job")
public class SysJobController {

	@Resource
	private SysJobService sysJobService;

    @Resource
    private SysJobManager sysJobManager;

    /**
     * 分页查询
     * @param page
     * @param query
     * @return
     */
    @GetMapping("/page")
    public ResponseResult page(Page<SysJobPageDTO> page, SysJobPageQuery query){
	    return ResponseResult.ok(sysJobService.page(page,query));
    }

    /**
     * 新增任务
     * @param sysJobAddForm
     * @return
     */
    @Log("新增任务")
    @PostMapping
    public ResponseResult add(@Valid @RequestBody SysJobAddForm sysJobAddForm) throws SchedulerException {
        if (!CronUtils.isValid(sysJobAddForm.getCronExpression())) {

            throw new CustomException(ErrorCodeEnum.PARAM_ILLEGAL.getCode(), "新增任务'" + sysJobAddForm.getJobName() + "'失败，Cron表达式不正确.");

        } else if (StrUtil.containsIgnoreCase(sysJobAddForm.getInvokeTarget(), "rmi:")) {

            throw new CustomException(ErrorCodeEnum.PARAM_ILLEGAL.getCode(), "新增任务'" + sysJobAddForm.getJobName() + "'失败，目标字符串不允许'rmi'调用");

        } else if (StrUtil.containsAnyIgnoreCase(sysJobAddForm.getInvokeTarget(), new String[] { "ldap:", "ldaps:" })) {

            throw new CustomException(ErrorCodeEnum.PARAM_ILLEGAL.getCode(), "新增任务'" + sysJobAddForm.getJobName() + "'失败，目标字符串不允许'ldap(s)'调用");

        } else if (StrUtil.containsAnyIgnoreCase(sysJobAddForm.getInvokeTarget(), new String[] { "http://", "https://" })) {

            throw new CustomException(ErrorCodeEnum.PARAM_ILLEGAL.getCode(), "新增任务'" + sysJobAddForm.getJobName() + "'失败，目标字符串不允许'http(s)'调用");

        } else if (StrUtil.containsAnyIgnoreCase(sysJobAddForm.getInvokeTarget(), ScheduleConstants.JOB_ERROR_STR)) {

            throw new CustomException(ErrorCodeEnum.PARAM_ILLEGAL.getCode(), "新增任务'" + sysJobAddForm.getJobName() + "'失败，目标字符串存在违规");

        } else if (!ScheduleUtils.whiteList(sysJobAddForm.getInvokeTarget())) {

	        throw new CustomException(ErrorCodeEnum.PARAM_ILLEGAL.getCode(), "新增任务'" + sysJobAddForm.getJobName() + "'失败，目标字符串不在白名单内");

        }
	    sysJobManager.createJob(sysJobAddForm);

        return ResponseResult.ok();
    }

	/**
	 * 修改任务
	 * @param sysJobEditForm
	 * @return
	 */
	@Log("修改任务")
	@PutMapping
	public ResponseResult edit(@Valid @RequestBody SysJobEditForm sysJobEditForm) throws SchedulerException {
		if (!CronUtils.isValid(sysJobEditForm.getCronExpression())) {

			throw new CustomException(ErrorCodeEnum.PARAM_ILLEGAL.getCode(), "新增任务'" + sysJobEditForm.getJobName() + "'失败，Cron表达式不正确.");

		} else if (StrUtil.containsIgnoreCase(sysJobEditForm.getInvokeTarget(), "rmi:")) {

			throw new CustomException(ErrorCodeEnum.PARAM_ILLEGAL.getCode(), "新增任务'" + sysJobEditForm.getJobName() + "'失败，目标字符串不允许'rmi'调用");

		} else if (StrUtil.containsAnyIgnoreCase(sysJobEditForm.getInvokeTarget(), new String[] { "ldap:", "ldaps:" })) {

			throw new CustomException(ErrorCodeEnum.PARAM_ILLEGAL.getCode(), "新增任务'" + sysJobEditForm.getJobName() + "'失败，目标字符串不允许'ldap(s)'调用");

		} else if (StrUtil.containsAnyIgnoreCase(sysJobEditForm.getInvokeTarget(), new String[] { "http://", "https://" })) {

			throw new CustomException(ErrorCodeEnum.PARAM_ILLEGAL.getCode(), "新增任务'" + sysJobEditForm.getJobName() + "'失败，目标字符串不允许'http(s)'调用");

		} else if (StrUtil.containsAnyIgnoreCase(sysJobEditForm.getInvokeTarget(), ScheduleConstants.JOB_ERROR_STR)) {

			throw new CustomException(ErrorCodeEnum.PARAM_ILLEGAL.getCode(), "新增任务'" + sysJobEditForm.getJobName() + "'失败，目标字符串存在违规");

		} else if (!ScheduleUtils.whiteList(sysJobEditForm.getInvokeTarget())) {

			throw new CustomException(ErrorCodeEnum.PARAM_ILLEGAL.getCode(), "新增任务'" + sysJobEditForm.getJobName() + "'失败，目标字符串不在白名单内");

		}

		sysJobManager.updateJob(sysJobEditForm);

		return ResponseResult.ok();
	}

	/**
	 * 定时任务状态修改
	 * @param sysJobStatusForm
	 * @return
	 * @throws SchedulerException
	 */
	@Log("定时任务状态修改")
	@PutMapping("/changeStatus")
	public ResponseResult changeStatus(@RequestBody SysJobStatusForm sysJobStatusForm) throws SchedulerException {
		sysJobManager.changeStatus(sysJobStatusForm);
		return ResponseResult.ok();
	}

	/**
	 * 立即执行一次
	 * @param id
	 * @return
	 * @throws SchedulerException
	 */
	@Log("定时任务立即执行")
	@GetMapping("/run/{id:\\d+}")
	public ResponseResult run(@PathVariable Long id) throws SchedulerException {
		sysJobManager.run(id);
		return ResponseResult.ok();
	}

	/**
	 * 删除任务
	 * @param id
	 * @return
	 * @throws SchedulerException
	 */
	@Log("删除任务")
	@DeleteMapping("/{id:\\d+}")
	public ResponseResult remove(@PathVariable Long id) throws SchedulerException {
		sysJobManager.deleteJob(id);
		return ResponseResult.ok();
	}

}
